package edu.qichen.onlineBlog.blogs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.qichen.onlineBlog.blogs.dto.*;
import edu.qichen.onlineBlog.blogs.mapper.BlogMapper;
import edu.qichen.onlineBlog.blogs.pojo.Blog;
import edu.qichen.onlineBlog.blogs.service.BlogService;
import edu.qichen.onlineBlog.comments.mapper.CommentsMapper;
import edu.qichen.onlineBlog.comments.pojo.Comments;
import edu.qichen.onlineBlog.framework.exception.BusinessException;
import edu.qichen.onlineBlog.framework.exception.ErrorCodeEnum;
import edu.qichen.onlineBlog.framework.utils.TokenUtils;
import edu.qichen.onlineBlog.framework.validata.ValidatorUtil;
import edu.qichen.onlineBlog.likes.mapper.LikesMapper;
import edu.qichen.onlineBlog.likes.pojo.Likes;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 功能:
 * 作者:程序员欧阳子韩
 * 日期:2024/4/26 14:42
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {
    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private LikesMapper likesMapper;
    @Autowired
    private CommentsMapper commentsMapper;

    @Override
    public BlogUserRes<BlogUserPageDto> queryById(Long id) {
        LambdaQueryWrapper<BlogUserPageDto> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BlogUserPageDto::getId, id);
        // 调用自定义的 select 方法，并传递参数
        List<BlogUserPageDto> blogList = blogMapper.select(wrapper, id);
        return BlogUserRes.<BlogUserPageDto>builder().blogs(blogList).build();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Blog addBlogs(AddBlogReq addBlogReq,HttpServletRequest request) {
        ValidatorUtil.validateEntity(addBlogReq);

        Blog blog = new Blog();
        blog.setTitle(addBlogReq.getTitle());
        blog.setContent(addBlogReq.getContent());
        blog.setCreateUser(addBlogReq.getCreateUser());
        blog.setCreateTime(addBlogReq.getCreateTime());
        blog.setUpdateTime(addBlogReq.getUpdateTime());

        HttpSession session = request.getSession();
        session.setAttribute("username", Objects.requireNonNull(TokenUtils.getCurrentUser()).getUsername());

        baseMapper.insert(blog);
        return blog;
    }

    @Override
    public PageBlogRes<BlogUserPageDto> queryBlogsPage(PageBlogReq pageBlogReq) {
        ValidatorUtil.validateEntity(pageBlogReq);

        long pageNum = pageBlogReq.getPageNum();
        long pageSize = pageBlogReq.getPageSize();
        IPage<BlogUserPageDto> page = new Page<>(pageNum, pageSize);// 这个 Page 对象可能不会被直接使用，只是用于传递参数

        QueryWrapper<BlogUserPageDto> wrapper = new QueryWrapper<>();

        // 调用自定义的 selectMapsPage 方法，并传递参数
        List<BlogUserPageDto> blogList = blogMapper.selectMapsPage(page, wrapper, pageBlogReq.getCreateUser());

        return PageBlogRes.<BlogUserPageDto>builder()
                .blogs(blogList)
                .pageNum(page.getCurrent())
                .pages(page.getPages())
                .pageSize(page.getSize())
                .total(page.getTotal())
                .build();
    }

    @Override
    public PageBlogRes<Blog> queryByTitle(String title) {
        LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Blog::getTitle, title);

        List<Blog> blogs = baseMapper.selectList(queryWrapper);
        long total = blogs.size();

        return PageBlogRes.<Blog>builder()
                .blogs(blogs)
                .total(total)
                .build();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Blog updateArticle(UpdateArticleReq updateArticleReq, HttpServletRequest request) {
        ValidatorUtil.validateEntity(updateArticleReq);

        Blog blog = new Blog();
        blog.setId(updateArticleReq.getId());
        blog.setTitle(updateArticleReq.getTitle());
        blog.setContent(updateArticleReq.getContent());

        baseMapper.updateById(blog);

        Blog updateBlog = baseMapper.selectById(updateArticleReq.getId());
        if (updateBlog == null) {
            throw BusinessException.build(ErrorCodeEnum.SERVER_UPDATE_QUERY_ERROR);
        }

        HttpSession session = request.getSession();
        session.setAttribute("username", Objects.requireNonNull(TokenUtils.getCurrentUser()).getUsername());
        return updateBlog;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean removeById(Long id) {
        LambdaQueryWrapper<Likes> likesWrapper = new LambdaQueryWrapper<>();
        likesWrapper.eq(Likes::getBlogId, id);

        List<Likes> likes = likesMapper.selectList(likesWrapper);
        likes.forEach(item -> {
            Integer likesId = item.getId();
            likesMapper.deleteById(likesId);
        });

        LambdaQueryWrapper<Comments> commentsWrapper = new LambdaQueryWrapper<>();
        commentsWrapper.eq(Comments::getBlogId, id);

        List<Comments> comments = commentsMapper.selectList(commentsWrapper);
        comments.forEach(item -> {
            Integer commentsId = item.getId();
            commentsMapper.deleteById(commentsId);
        });

        baseMapper.deleteById(id);
        return true;
    }

    @Override
    public PageBlogRes<BlogUserPageDto> newBlogs(PageBlogReq pageBlogReq) {
        ValidatorUtil.validateEntity(pageBlogReq);

        long pageNum = pageBlogReq.getPageNum();
        long pageSize = pageBlogReq.getPageSize();
        IPage<BlogUserPageDto> page = new Page<>(pageNum, pageSize);// 这个 Page 对象可能不会被直接使用，只是用于传递参数

        QueryWrapper<BlogUserPageDto> wrapper = new QueryWrapper<>();

        // 调用自定义的 selectMapsPage 方法，并传递参数
        List<BlogUserPageDto> blogList = blogMapper.selectMapsPage(page, wrapper, pageBlogReq.getCreateUser());

        return PageBlogRes.<BlogUserPageDto>builder()
                .blogs(blogList)
                .pageNum(page.getCurrent())
                .pages(page.getPages())
                .pageSize(page.getSize())
                .total(page.getTotal())
                .build();
    }
}
